home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q1082.dms / q1082.adf / src.lzh / Fig / draw.c < prev    next >
C/C++ Source or Header  |  1991-07-18  |  8KB  |  372 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1988 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    March 1988.
  6.  *
  7.  *    %W%    %G%
  8. */
  9. #include "fig.h"
  10. #include "resources.h"
  11. #include "object.h"
  12. #include "paintop.h"
  13.  
  14. extern int        pointmarker_shown, compoundbox_shown;
  15. extern int        background_color, foreground_color;
  16. extern PIXRECTREC    dot;
  17.  
  18. /*
  19. erase_objects(objects)
  20. F_compound    *objects;
  21. {
  22.     erase_arcs(objects->arcs);
  23.     erase_ellipses(objects->ellipses);
  24.     erase_lines(objects->lines);
  25.     erase_texts(objects->texts);
  26.     erase_splines(objects->splines);
  27.     erase_compounds(objects->compounds);
  28.     }
  29. */
  30.  
  31. erase_splines(splines)
  32. F_spline    *splines;
  33. {
  34.     F_spline    *s;
  35.  
  36.     pw_batch_on(canvas_pixwin);
  37.     for (s = splines; s != NULL; s = s->next) {
  38.         if (pointmarker_shown) toggle_splinepointmarker(s);
  39.         draw_spline(s, ERASE);
  40.         };
  41.     pw_batch_off(canvas_pixwin);
  42.     }
  43.  
  44. erase_ellipses(ellipses)
  45. F_ellipse    *ellipses;
  46. {
  47.     F_ellipse    *e;
  48.  
  49.     pw_batch_on(canvas_pixwin);
  50.     for (e = ellipses; e != NULL; e = e->next) {
  51.         if (pointmarker_shown) toggle_ellipsepointmarker(e);
  52.         draw_ellipse(e, background_color);
  53.         };
  54.     pw_batch_off(canvas_pixwin);
  55.     }
  56.  
  57. erase_arcs(arcs)
  58. F_arc    *arcs;
  59. {
  60.     F_arc    *a;
  61.  
  62.     pw_batch_on(canvas_pixwin);
  63.     for (a = arcs; a != NULL; a = a->next) {
  64.         if (pointmarker_shown) toggle_arcpointmarker(a);
  65.         draw_arc(a, background_color);
  66.         };
  67.     pw_batch_off(canvas_pixwin);
  68.     }
  69.  
  70. erase_compounds(compounds)
  71. F_compound    *compounds;
  72. {
  73.     F_compound    *c;
  74.  
  75.     for (c = compounds; c != NULL; c = c->next) {
  76.         if (compoundbox_shown) draw_compoundbox(c, INV_PAINT);
  77.         erase_compound(c);
  78.         };
  79.     }
  80.  
  81. erase_lines(lines)
  82. F_line    *lines;
  83. {
  84.     F_line    *l;
  85.  
  86.     for (l = lines; l != NULL; l = l->next) {
  87.         if (pointmarker_shown) toggle_linepointmarker(l);
  88.         draw_line(l, ERASE);
  89.         };
  90.     }
  91.  
  92. erase_texts(texts)
  93. F_text    *texts;
  94. {
  95.     F_text    *t;
  96.  
  97.     for (t = texts; t != NULL; t = t->next) {
  98.         draw_text(t, INV_PAINT);
  99.         };
  100.     }
  101.  
  102. /*
  103. draw_objects(objects)
  104. F_compound    *objects;
  105. {
  106.     draw_arcs(objects->arcs);
  107.     draw_ellipses(objects->ellipses);
  108.     draw_lines(objects->lines);
  109.     draw_texts(objects->texts);
  110.     draw_splines(objects->splines);
  111.     draw_compounds(objects->compounds);
  112.     }
  113. */
  114.  
  115. draw_ellipses(ellipses)
  116. F_ellipse    *ellipses;
  117. {
  118.     F_ellipse    *e;
  119.  
  120.     pw_batch_on(canvas_pixwin);
  121.     for (e = ellipses; e != NULL; e = e->next) {
  122.         draw_ellipse(e, foreground_color);
  123.         if (pointmarker_shown) toggle_ellipsepointmarker(e);
  124.         };
  125.     pw_batch_off(canvas_pixwin);
  126.     }
  127.  
  128. draw_arcs(arcs)
  129. F_arc    *arcs;
  130. {
  131.     F_arc    *a;
  132.  
  133.     pw_batch_on(canvas_pixwin);
  134.     for (a = arcs; a != NULL; a = a->next) {
  135.         draw_arc(a, foreground_color);
  136.         if (pointmarker_shown) toggle_arcpointmarker(a);
  137.         };
  138.     pw_batch_off(canvas_pixwin);
  139.     }
  140.  
  141. draw_lines(lines)
  142. F_line    *lines;
  143. {
  144.     F_line    *l;
  145.  
  146.     pw_batch_on(canvas_pixwin);
  147.     for (l = lines; l != NULL; l = l->next) {
  148.         draw_line(l, PAINT);
  149.         if (pointmarker_shown) toggle_linepointmarker(l);
  150.         };
  151.     pw_batch_off(canvas_pixwin);
  152.     }
  153.  
  154. draw_splines(splines)
  155. F_spline    *splines;
  156. {
  157.     F_spline    *s;
  158.  
  159.     pw_batch_on(canvas_pixwin);
  160.     for (s = splines; s != NULL; s = s->next) {
  161.         draw_spline(s, PAINT);
  162.         if (pointmarker_shown) toggle_splinepointmarker(s);
  163.         };
  164.     pw_batch_off(canvas_pixwin);
  165.     }
  166.  
  167. draw_texts(texts)
  168. F_text    *texts;
  169. {
  170.     F_text    *t;
  171.  
  172.     for (t = texts; t != NULL; t = t->next) {
  173.         draw_text(t, PAINT);
  174.         };
  175.     }
  176.  
  177. draw_compounds(compounds)
  178. F_compound    *compounds;
  179. {
  180.     F_compound    *c;
  181.  
  182.     for (c = compounds; c != NULL; c = c->next) {
  183.         draw_compound(c);
  184.         if (compoundbox_shown) draw_compoundbox(c, INV_PAINT);
  185.         };
  186.     }
  187.  
  188. /*    draw arrow heading from (x1, y1) to (x2, y2)    */
  189.  
  190. draw_arrow(x1, y1, x2, y2, arrow, op)
  191. int    x1, y1, x2, y2, op;
  192. F_arrow    *arrow;
  193. {
  194.     float    x, y, xb, yb, dx, dy, l, sina, cosa;
  195.     int    xc, yc, xd, yd;
  196.     float    wid = arrow->wid, ht = arrow->ht;
  197.  
  198.     dx = x2 - x1;  dy = y1 - y2;
  199.     l = sqrt((double)(dx*dx + dy*dy));
  200.     sina = dy / l;  cosa = dx / l;
  201.     xb = x2*cosa - y2*sina;
  202.     yb = x2*sina + y2*cosa;
  203.     x = xb - ht;
  204.     y = yb - wid / 2;
  205.     xc = x*cosa + y*sina + .5;
  206.     yc = -x*sina + y*cosa + .5;
  207.     y = yb + wid / 2;
  208.     xd = x*cosa + y*sina + .5;
  209.     yd = -x*sina + y*cosa + .5;
  210.     pw_vector(canvas_pixwin, xc, yc, x2, y2, op, 1);
  211.     pw_vector(canvas_pixwin, xd, yd, x2, y2, op, 1);
  212.     }
  213.  
  214. draw_spline(spline, op)
  215. F_spline    *spline;
  216. int        op;
  217. {
  218.     if (int_spline(spline))
  219.         draw_intspline(spline, op);
  220.     else if (spline->type == T_CLOSED_NORMAL)
  221.         draw_closed_spline(spline, op);
  222.     else if (spline->type == T_OPEN_NORMAL)
  223.         draw_open_spline(spline, op);
  224.     }
  225.  
  226. #define        STACK_DEPTH        32
  227. typedef        struct stack {
  228.             float    x1, y1, x2, y2, x3, y3, x4, y4;
  229.             }
  230.         Stack;
  231. static Stack    stack[20];
  232. static Stack    *stack_top;
  233. static int    stack_count;
  234.  
  235. clear_stack()
  236. {
  237.     stack_top = stack;
  238.     stack_count = 0;
  239.     }
  240.  
  241. push(x1, y1, x2, y2, x3, y3, x4, y4)
  242. float    x1, y1, x2, y2, x3, y3, x4, y4;
  243. {
  244.     stack_top->x1 = x1;
  245.     stack_top->y1 = y1;
  246.     stack_top->x2 = x2;
  247.     stack_top->y2 = y2;
  248.     stack_top->x3 = x3;
  249.     stack_top->y3 = y3;
  250.     stack_top->x4 = x4;
  251.     stack_top->y4 = y4;
  252.     stack_top++;
  253.     stack_count++;
  254.     }
  255.  
  256. int
  257. pop(x1, y1, x2, y2, x3, y3, x4, y4)
  258. float    *x1, *y1, *x2, *y2, *x3, *y3, *x4, *y4;
  259. {
  260.     if (stack_count == 0) return(0);
  261.     stack_top--;
  262.     stack_count--;
  263.     *x1 = stack_top->x1;
  264.     *y1 = stack_top->y1;
  265.     *x2 = stack_top->x2;
  266.     *y2 = stack_top->y2;
  267.     *x3 = stack_top->x3;
  268.     *y3 = stack_top->y3;
  269.     *x4 = stack_top->x4;
  270.     *y4 = stack_top->y4;
  271.     return(1);
  272.     }
  273.  
  274. draw_line(line, op)
  275. F_line    *line;
  276. int    op;
  277. {
  278.     F_point            *point;
  279.     int            xx, yy, x, y;
  280.  
  281.     point = line->points;
  282.     x = point->x;
  283.     y = point->y;
  284.     if (line->points->next == NULL) { /* A single point */
  285. #ifndef    X11
  286.         pw_write(canvas_pixwin, x, y, 1, 1, op, &dot, 0, 0);
  287. #else
  288.         XDrawPoint(tool_d, canvas_pixwin, gccache[op], x, y);
  289. #endif    X11
  290.         return;
  291.         }
  292.     if (line->back_arrow) /* backward arrow  */
  293.         draw_arrow(point->next->x, point->next->y, x, y, 
  294.         line->back_arrow, op);
  295.     for (point = point->next; point != NULL; point = point->next) {
  296.         draw_line_segment(line->style, line->style_val, 
  297.                 x, y, point->x, point->y, op);
  298.         xx = x; yy = y;
  299.         x = point->x;
  300.         y = point->y;
  301.         }
  302.     if (line->for_arrow) 
  303.         draw_arrow(xx, yy, x, y, line->for_arrow, op);
  304.     }
  305.  
  306. #define        round(x)    ((int)((x) + .5))
  307. #define        dash_length    style_val
  308. #define        dot_gap        style_val
  309.  
  310. draw_line_segment(line_style, style_val, x1, y1, x2, y2, op)
  311. int    line_style, x1, y1, x2, y2, op;
  312. float    style_val;
  313. {
  314.     switch (line_style) {
  315.         case SOLID_LINE :
  316.         pw_vector(canvas_pixwin, x1, y1, x2, y2, op, 1);
  317.         break;
  318.         case DASH_LINE : {
  319.         float    x, y, leng, dx, dy, dash_x, dash_y;
  320.         float    spacing_leng, space_x, space_y;
  321.         int    num_spacing;
  322.  
  323.         dx = x2 - x1;
  324.         dy = y2 - y1;
  325.         leng = sqrt((double)(dx*dx + dy*dy));
  326.         if (leng <= dash_length) {
  327.             pw_vector(canvas_pixwin, x1, y1, x2, y2, op, 1);
  328.             break;
  329.             }
  330.         dash_x = dash_length * dx / leng;
  331.         dash_y = dash_length * dy / leng;
  332.         num_spacing = (leng - dash_length) / (2 * dash_length);
  333.         spacing_leng = (leng - dash_length * (num_spacing + 1)) /
  334.                 ((float)num_spacing);
  335.         space_x = spacing_leng * dx / leng;
  336.         space_y = spacing_leng * dy / leng;
  337.         dx = dash_x + space_x;  dy = dash_y + space_y;
  338.         for (x = x1, y = y1; leng > 0; 
  339.             x += dx, y += dy, leng -= dash_length + spacing_leng) {
  340.             pw_vector(canvas_pixwin, round(x), round(y), 
  341.                 round(x + dash_x), round(y + dash_y), op, 1);
  342.             }
  343.         break;
  344.         }
  345.         case DOTTED_LINE : {
  346.         float    x, y, leng, dx, dy, gap_x, gap_y;
  347.         int    n, color;
  348.  
  349.         dot_gap += 1.0;
  350.         dx = x2 - x1;
  351.         dy = y2 - y1;
  352.         leng = sqrt((double)(dx*dx + dy*dy)) - 1;
  353.         n = round(leng/dot_gap);
  354.         if (op == PAINT)
  355.             color = foreground_color;
  356.         else
  357.             color = background_color;
  358.         if (n <= 1) {
  359.             pw_put(canvas_pixwin, x1, y1, color);
  360.             pw_put(canvas_pixwin, x2, y2, color);
  361.             break;
  362.             }
  363.         dot_gap = leng / n;
  364.         gap_x = dot_gap * dx / leng;
  365.         gap_y = dot_gap * dy / leng;
  366.         for (x = x1, y = y1; n-- >= 0; x += gap_x, y += gap_y)
  367.             pw_put(canvas_pixwin, round(x), round(y), color);
  368.         break;
  369.         }
  370.         }
  371.     }
  372.